﻿using Player.Weapons;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;

namespace Player.Weapons
{
    public class Weapon:IDisposable
    {
        public string WeaponName { get; } = "Wand";
        public int SlotNum { get; set; } = 3;

        protected AttackWay attackWay;
        internal PlayerBody playerBody;

        

        /// <summary>
        /// 只给子类用的构造函数
        /// </summary>
        /// <param name="weaponName">武器名称(首字母大写)</param>
        /// <param name="playerBody">PlayerBody(玩家本体)</param>
        protected Weapon(string weaponName, PlayerBody playerBody)
        {
            WeaponName = weaponName;

            this.playerBody = playerBody;

        }

        /// <summary>
        /// 创建武器
        /// </summary>
        /// <param name="weaponName">武器名称(首字母大写)</param>
        /// <param name="playerBody">PlayerBody(玩家本体)</param>
        /// <returns></returns>
        public static Weapon CreateWeapon(string weaponName, PlayerBody playerBody)
        {
            Assembly AsmDevice = Assembly.GetExecutingAssembly();//加载命名空间    
            Type classType = AsmDevice.GetType("Player.Weapons." + weaponName);//获取命名空间下的类
            object classObj = Activator.CreateInstance(classType,new object[] { playerBody });//实例化反射回来的指定类
            return (Weapon)classObj;
        }

        /// <summary>
        /// 槽位，核心
        /// </summary>
        internal Dictionary<int, Core> coreDic = new Dictionary<int, Core>();
        internal List<Core> cores = new List<Core>();

        /// <summary>
        /// 子弹效果字典
        /// <para>Type,等级</para>
        /// </summary>
        internal Dictionary<Type, int> BulletEffectLevel = new Dictionary<Type, int>();



        public virtual void AttackStart()
        {
            attackWay.AttackStart();
        }

        public virtual void AttackEnd()
        {
            attackWay.AttackEnd();
        }

        public virtual void Updata()
        {
            attackWay.Update_Other();
        }

        /// <summary>
        /// 设置子弹效果
        /// </summary>
        /// <param name="beType">子弹效果类Type</param>
        /// <param name="level">效果等级,<=0则为取消效果</param>
        public void SetBulletEffect(Type beType, int level)
        {
            if (BulletEffectLevel.ContainsKey(beType))
            {
                if (level <= 0)
                {
                    BulletEffectLevel.Remove(beType);
                }
                else
                {
                    BulletEffectLevel[beType] = level;
                }
            }
        }

        /// <summary>
        /// 获取核心
        /// </summary>
        /// <param name="slotID">槽位ID</param>
        /// <param name="core">获得的核心</param>
        /// <returns>是否成功</returns>
        public bool GetCore(int slotID, Core core)
        {
            if (coreDic.ContainsKey(slotID))
            {
                return false;
            }
            SetCore_m(slotID, core);
            return true;
        }

        /// <summary>
        /// 移除核心
        /// </summary>
        /// <param name="slotID">槽位ID</param>
        public void RemoveCore(int slotID)
        {
            if (coreDic.ContainsKey(slotID))
            {
                var oldCore = coreDic[slotID];
                var coreTyp = GetCoreType(oldCore);
                SetBulletEffect(coreTyp, BulletEffectLevel[coreTyp]--);
                coreDic.Remove(slotID);
            }
        }

        /// <summary>
        /// 改变核心
        /// </summary>
        /// <param name="slotID">槽位ID</param>
        /// <param name="core">新核心</param>
        public void ChangeCore(int slotID, Core core)
        {
            RemoveCore(slotID);
            SetCore_m(slotID, core);
        }

        /// <summary>
        /// 设置核心,只有这里会改变核心字典
        /// </summary>
        /// <param name="slotID">槽位ID</param>
        /// <param name="core">核心</param>
        private void SetCore_m(int slotID, Core core)
        {
            if (coreDic.ContainsKey(slotID))
            {

            }
            coreDic.Add(slotID, core);


            int level = 0;
            foreach (var item in coreDic.Values)
            {
                if (item == core)
                {
                    level++;
                }
            }
            SetBulletEffect(GetCoreType(core), level);
            cores = coreDic.Values.ToList();
        }

        private Type GetCoreType(Core core)
        {
            Assembly AsmDevice = Assembly.GetExecutingAssembly();//加载命名空间    
            return AsmDevice.GetType("Player.Weapons." + WeaponName + "s." + core.ToString().ToUpper());//获取命名空间下的类
        }

        /// <summary>
        /// 设置玩家的攻击方式
        /// </summary>
        private void SetAttackWay()
        {
            string wayName = "DefaultWay";//攻击方式类名称
            if (coreDic.Count >= 3)
            {
                //TODO使用IF判断填充攻击方式 
            }

            Assembly AsmDevice = Assembly.GetExecutingAssembly();
            var atkType = AsmDevice.GetType("Player.Weapons." + WeaponName + "s." + wayName);
            object classObj = Activator.CreateInstance(atkType, playerBody);//实例化反射回来的指定类
            attackWay = (AttackWay)classObj;
        }


        #region 手动实现回收机制
        bool disposed = false;

        public void Dispose()
        {
            //必须为true
            Dispose(true);
            //通知垃圾回收机制不再调用终结器（析构器）
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 非密封类修饰用protected virtual
        /// 密封类修饰用private
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposed)
            {
                return;
            }
            if (disposing)
            {
                if (attackWay != null)
                {
                    attackWay.Dispose();
                }
            }
            if (playerBody != null)
            {
                playerBody = null;
            }
            if (cores!=null)
            {
                cores = null;
            }
            if (coreDic!=null)
            {
                coreDic = null;
            }
            if (BulletEffectLevel!=null)
            {
                BulletEffectLevel = null;
            }
            //让类型知道自己已经被释放
            disposed = true;
        }

        ~Weapon(){
            Dispose(false);
        }
        #endregion


    }
}


